const CloneDeep = require('../template')

console.log("=== CloneDeep 高级方法测试 ===")

// 测试循环引用深拷贝
console.log(
  "循环引用深拷贝:", (() => {
    const obj = { a: 1 }
    obj.self = obj

    try {
      const cloned = CloneDeep.cloneDeepWithCircular(obj)
      return cloned.a === 1 &&
        cloned.self === cloned &&
        cloned !== obj
    } catch (error) {
      return true // 循环引用应该正确处理
    }
  })()
)

// 测试自定义拷贝函数深拷贝
console.log(
  "自定义拷贝函数深拷贝:", (() => {
    const obj = { a: 1, b: 'test', c: { nested: 2 } }
    const cloned = CloneDeep.cloneDeepWithCustomizer(obj, (value, key) => {
      if (key === 'b') return value.toUpperCase()
      if (typeof value === 'number') return value * 2
      return undefined // 使用默认拷贝
    })

    return cloned.a === 2 &&
      cloned.b === 'TEST' &&
      typeof cloned.c === 'object' &&
      cloned.c.nested === 4 &&
      cloned !== obj &&
      cloned.c !== obj.c
  })()
)

// 测试类型过滤深拷贝
console.log(
  "类型过滤深拷贝:", (() => {
    const obj = { a: 1, b: 'test', c: { nested: 2 }, d: [1, 2, 3] }
    const cloned = CloneDeep.cloneDeepWithTypes(obj, ['number', 'string'])

    return cloned.a === 1 &&
      cloned.b === 'test' &&
      cloned.c === undefined &&
      cloned.d === undefined &&
      cloned !== obj
  })()
)

// 测试深度限制深拷贝
console.log(
  "深度限制深拷贝:", (() => {
    const obj = { a: { b: { c: { d: 'deep' } } } }
    const cloned = CloneDeep.cloneDeepWithDepth(obj, 2)

    return typeof cloned === 'object' &&
      typeof cloned.a === 'object' &&
      typeof cloned.a.b === 'object' &&
      cloned.a.b.c === obj.a.b.c && // 超过深度限制，保持引用
      cloned !== obj &&
      cloned.a !== obj.a &&
      cloned.a.b !== obj.a.b
  })()
)

// 测试属性过滤深拷贝
console.log(
  "属性过滤深拷贝:", (() => {
    const obj = { a: 1, b: 2, c: 3, d: 4 }
    const cloned = CloneDeep.cloneDeepWithFilter(obj, (value, key) => {
      return key !== 'c' && value > 1
    })

    return cloned.a === undefined &&
      cloned.b === 2 &&
      cloned.c === undefined &&
      cloned.d === 4 &&
      cloned !== obj
  })()
)

// 测试属性映射深拷贝
console.log(
  "属性映射深拷贝:", (() => {
    const obj = { a: 1, b: 2, c: 3 }
    const cloned = CloneDeep.cloneDeepWithMapper(obj, (value, key) => {
      return { [`new_${key}`]: value * 2 }
    })

    return cloned.new_a === 2 &&
      cloned.new_b === 4 &&
      cloned.new_c === 6 &&
      !('a' in cloned) &&
      !('b' in cloned) &&
      !('c' in cloned) &&
      cloned !== obj
  })()
)

// 测试验证深拷贝
console.log(
  "验证深拷贝:", (() => {
    const obj = { name: 'John', age: 30, email: 'john@example.com' }
    const schema = {
      name: { type: 'string', required: true },
      age: { type: 'number', min: 0, max: 150 },
      email: { type: 'string', pattern: /@/ }
    }

    try {
      const cloned = CloneDeep.cloneDeepWithValidation(obj, schema)
      return cloned.name === 'John' &&
        cloned.age === 30 &&
        cloned.email === 'john@example.com' &&
        cloned !== obj
    } catch (error) {
      return false
    }
  })()
)

// 测试异步深拷贝
console.log(
  "异步深拷贝:", (() => {
    const obj = { a: 1, b: 'test' }

    return CloneDeep.cloneDeepAsync(obj, async (value, key) => {
      if (typeof value === 'string') return value.toUpperCase()
      return value
    }).then(cloned => {
      return cloned.a === 1 &&
        cloned.b === 'TEST' &&
        cloned !== obj
    }).catch(() => false)
  })()
)

// 测试并发深拷贝
console.log(
  "并发深拷贝:", (() => {
    const obj = { a: 1, b: 2, c: 3, d: 4, e: 5 }

    return CloneDeep.cloneDeepConcurrent(obj, async (value, key) => {
      await new Promise(resolve => setTimeout(resolve, 10))
      return value * 2
    }, 3).then(cloned => {
      return cloned.a === 2 &&
        cloned.b === 4 &&
        cloned.c === 6 &&
        cloned.d === 8 &&
        cloned.e === 10 &&
        cloned !== obj
    }).catch(() => false)
  })()
)

// 测试统计深拷贝
console.log(
  "统计深拷贝:", (() => {
    const obj = { a: 1, b: { c: 2 }, d: [3, 4] }
    const result = CloneDeep.cloneDeepWithStats(obj)

    return typeof result === 'object' &&
      typeof result.data === 'object' &&
      typeof result.stats === 'object' &&
      result.data.a === 1 &&
      result.data.b.c === 2 &&
      Array.isArray(result.data.d) &&
      result.data.d[0] === 3 &&
      result.data.d[1] === 4 &&
      result.stats.objectsCopied > 0 &&
      result.stats.arraysCopied > 0 &&
      result.stats.primitivesCopied > 0
  })()
)

// 测试复杂嵌套结构深拷贝
console.log(
  "复杂嵌套结构深拷贝:", (() => {
    const obj = {
      users: [
        { id: 1, profile: { name: 'Alice', settings: { theme: 'dark' } } },
        { id: 2, profile: { name: 'Bob', settings: { theme: 'light' } } }
      ],
      meta: { total: 2, page: 1 },
      config: { api: { baseUrl: 'https://api.example.com' } }
    }

    const cloned = CloneDeep.cloneDeep(obj)

    return Array.isArray(cloned.users) &&
      cloned.users.length === 2 &&
      cloned.users[0].id === 1 &&
      cloned.users[0].profile.name === 'Alice' &&
      cloned.users[0].profile.settings.theme === 'dark' &&
      cloned.users[1].id === 2 &&
      cloned.users[1].profile.name === 'Bob' &&
      cloned.users[1].profile.settings.theme === 'light' &&
      cloned.meta.total === 2 &&
      cloned.meta.page === 1 &&
      cloned.config.api.baseUrl === 'https://api.example.com' &&
      cloned !== obj &&
      cloned.users !== obj.users &&
      cloned.users[0] !== obj.users[0] &&
      cloned.users[0].profile !== obj.users[0].profile &&
      cloned.users[0].profile.settings !== obj.users[0].profile.settings &&
      cloned.meta !== obj.meta &&
      cloned.config !== obj.config &&
      cloned.config.api !== obj.config.api
  })()
)

// 测试Map和Set深拷贝
console.log(
  "Map和Set深拷贝:", (() => {
    const map = new Map([['a', 1], ['b', 2]])
    const set = new Set([1, 2, 3])
    const obj = { map, set, data: 'test' }

    const cloned = CloneDeep.cloneDeep(obj)

    return cloned.map instanceof Map &&
      cloned.map.size === 2 &&
      cloned.map.get('a') === 1 &&
      cloned.map.get('b') === 2 &&
      cloned.set instanceof Set &&
      cloned.set.size === 3 &&
      cloned.set.has(1) &&
      cloned.set.has(2) &&
      cloned.set.has(3) &&
      cloned.data === 'test' &&
      cloned !== obj &&
      cloned.map !== map &&
      cloned.set !== set
  })()
)

// 测试WeakMap和WeakSet深拷贝
console.log(
  "WeakMap和WeakSet深拷贝:", (() => {
    const weakMap = new WeakMap()
    const weakSet = new WeakSet()
    const obj1 = { id: 1 }
    const obj2 = { id: 2 }

    weakMap.set(obj1, 'value1')
    weakSet.add(obj2)

    const obj = { weakMap, weakSet, data: 'test' }

    try {
      const cloned = CloneDeep.cloneDeep(obj)
      return cloned.data === 'test' &&
        cloned.weakMap === undefined && // WeakMap无法深拷贝
        cloned.weakSet === undefined && // WeakSet无法深拷贝
        cloned !== obj
    } catch (error) {
      return true // WeakMap/WeakSet无法深拷贝是正常的
    }
  })()
)

// 测试TypedArray深拷贝
console.log(
  "TypedArray深拷贝:", (() => {
    const uint8Array = new Uint8Array([1, 2, 3, 4])
    const float32Array = new Float32Array([1.1, 2.2, 3.3])
    const obj = { uint8Array, float32Array, data: 'test' }

    const cloned = CloneDeep.cloneDeep(obj)

    return cloned.uint8Array instanceof Uint8Array &&
      cloned.uint8Array.length === 4 &&
      cloned.uint8Array[0] === 1 &&
      cloned.uint8Array[1] === 2 &&
      cloned.uint8Array[2] === 3 &&
      cloned.uint8Array[3] === 4 &&
      cloned.float32Array instanceof Float32Array &&
      cloned.float32Array.length === 3 &&
      Math.abs(cloned.float32Array[0] - 1.1) < 0.001 &&
      Math.abs(cloned.float32Array[1] - 2.2) < 0.001 &&
      Math.abs(cloned.float32Array[2] - 3.3) < 0.001 &&
      cloned.data === 'test' &&
      cloned !== obj &&
      cloned.uint8Array !== uint8Array &&
      cloned.float32Array !== float32Array
  })()
)

// 测试ArrayBuffer深拷贝
console.log(
  "ArrayBuffer深拷贝:", (() => {
    const buffer = new ArrayBuffer(8)
    const view = new Uint8Array(buffer)
    view[0] = 1
    view[1] = 2
    view[2] = 3

    const obj = { buffer, view, data: 'test' }

    const cloned = CloneDeep.cloneDeep(obj)

    return cloned.buffer instanceof ArrayBuffer &&
      cloned.buffer.byteLength === 8 &&
      cloned.view instanceof Uint8Array &&
      cloned.view.length === 8 &&
      cloned.view[0] === 1 &&
      cloned.view[1] === 2 &&
      cloned.view[2] === 3 &&
      cloned.data === 'test' &&
      cloned !== obj &&
      cloned.buffer !== buffer &&
      cloned.view !== view
  })()
)

// 测试DataView深拷贝
console.log(
  "DataView深拷贝:", (() => {
    const buffer = new ArrayBuffer(8)
    const dataView = new DataView(buffer)
    dataView.setUint8(0, 1)
    dataView.setUint8(1, 2)

    const obj = { dataView, data: 'test' }

    const cloned = CloneDeep.cloneDeep(obj)

    return cloned.dataView instanceof DataView &&
      cloned.dataView.byteLength === 8 &&
      cloned.dataView.getUint8(0) === 1 &&
      cloned.dataView.getUint8(1) === 2 &&
      cloned.data === 'test' &&
      cloned !== obj &&
      cloned.dataView !== dataView
  })()
)

// 测试Error对象深拷贝
console.log(
  "Error对象深拷贝:", (() => {
    const error = new Error('Test error')
    error.code = 'TEST_ERROR'
    error.details = { line: 10, column: 5 }

    const obj = { error, data: 'test' }

    const cloned = CloneDeep.cloneDeep(obj)

    return cloned.error instanceof Error &&
      cloned.error.message === 'Test error' &&
      cloned.error.code === 'TEST_ERROR' &&
      typeof cloned.error.details === 'object' &&
      cloned.error.details.line === 10 &&
      cloned.error.details.column === 5 &&
      cloned.data === 'test' &&
      cloned !== obj &&
      cloned.error !== error &&
      cloned.error.details !== error.details
  })()
)

// 测试Promise深拷贝
console.log(
  "Promise深拷贝:", (() => {
    const promise = Promise.resolve('test')
    const obj = { promise, data: 'test' }

    try {
      const cloned = CloneDeep.cloneDeep(obj)
      return cloned.data === 'test' &&
        cloned.promise === undefined && // Promise无法深拷贝
        cloned !== obj
    } catch (error) {
      return true // Promise无法深拷贝是正常的
    }
  })()
)

// 测试Generator深拷贝
console.log(
  "Generator深拷贝:", (() => {
    function* generator() {
      yield 1
      yield 2
      yield 3
    }

    const gen = generator()
    const obj = { gen, data: 'test' }

    try {
      const cloned = CloneDeep.cloneDeep(obj)
      return cloned.data === 'test' &&
        cloned.gen === undefined && // Generator无法深拷贝
        cloned !== obj
    } catch (error) {
      return true // Generator无法深拷贝是正常的
    }
  })()
)

// 测试Proxy深拷贝
console.log(
  "Proxy深拷贝:", (() => {
    const target = { a: 1, b: 2 }
    const proxy = new Proxy(target, {
      get(target, prop) {
        return target[prop] * 2
      }
    })

    const obj = { proxy, data: 'test' }

    try {
      const cloned = CloneDeep.cloneDeep(obj)
      return cloned.data === 'test' &&
        cloned.proxy === undefined && // Proxy无法深拷贝
        cloned !== obj
    } catch (error) {
      return true // Proxy无法深拷贝是正常的
    }
  })()
)

console.log("=== CloneDeep 高级方法测试完成 ===")
